#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <sys/time.h>
 
#include "data_type.h"
#include "cube.h"
#include "cube_define.h"
#include "cube_record.h"

#include "sm2.h"
#include "tcm_constants.h"
#include "app_struct.h"
#include "pik_struct.h"
#include "tcmfunc.h"
#include "owner_define.h"

#include "owner_init.h"

BYTE Buf[DIGEST_SIZE*32];
// add para lib_include
int owner_init_init(void * sub_proc, void * para)
{
	int ret;
	// add yorself's module init func here
	return 0;
}
int owner_init_start(void * sub_proc, void * para)
{
	int ret;
	void * recv_msg;
	int type;
	int subtype;
	// add yorself's module exec func here
	while(1)
	{
		usleep(time_val.tv_usec);
		ret=ex_module_recvmsg(sub_proc,&recv_msg);
		if(ret<0)
			continue;
		if(recv_msg==NULL)
			continue;
		type=message_get_type(recv_msg);
		subtype=message_get_subtype(recv_msg);
		if(!memdb_find_recordtype(type,subtype))
		{
			printf("message format (%d %d) is not registered!\n",
			message_get_type(recv_msg),message_get_subtype(recv_msg));
			continue;
		}
		if((type==TYPE(GENERAL_RETURN))&&(subtype==SUBTYPE(GENERAL_RETURN,STRING)))
		{
			ret=proc_owner_init(sub_proc,recv_msg);
		}
	}
	return 0;
}

int proc_owner_init(void * sub_proc,void * recv_msg)
{
	int ret;
	RECORD(GENERAL_RETURN,STRING) * owner_name;
	RECORD(OWNER,PUBLIC_DATA) * owner_pubdata;
	RECORD(OWNER,PRIVATE_DATA) * owner_privdata;
	BYTE pubkey_XY[68];
	DB_RECORD * db_record;
	void * new_msg;

	ret=message_get_record(recv_msg,&owner_name,0);
	if(ret<0)
		return ret;

	db_record = memdb_find_first(TYPE_PAIR(OWNER,PUBLIC_DATA),"user_name",owner_name->name);
	if(db_record==NULL)
	{
		owner_privdata=Talloc0(sizeof(*owner_privdata));
		if(owner_privdata==NULL)
			return -ENOMEM;
		owner_pubdata=Talloc0(sizeof(*owner_pubdata));
		if(owner_pubdata==NULL)
			return -ENOMEM;
		owner_privdata->privkey_size=64;
		ret = GM_GenSM2keypair(Buf, &owner_privdata->privkey_size,pubkey_XY);
		if(ret<0)
			return -EINVAL;			
		proc_share_data_getvalue("uuid",owner_privdata->uuid);
		owner_privdata->user_name=dup_str(owner_name->name,DIGEST_SIZE);

		owner_privdata->privkey_data=Talloc0(owner_privdata->privkey_size);
		if(owner_privdata->privkey_data==NULL)
			return -ENOMEM;	

		Memcpy(owner_privdata->privkey_data,Buf,owner_privdata->privkey_size);	
		Memset(Buf,0,DIGEST_SIZE);
		Strncpy(Buf,owner_name->return_value,DIGEST_SIZE);
		calculate_context_sm3(Buf,DIGEST_SIZE,owner_privdata->passwd);

		memdb_store(owner_privdata,TYPE_PAIR(OWNER,PRIVATE_DATA),NULL);

		Memcpy(owner_pubdata->uuid,	owner_privdata->uuid,DIGEST_SIZE);
		owner_pubdata->user_name=dup_str(owner_name->name,0);
		owner_pubdata->pubkey_size=64;
		owner_pubdata->pubkey_data=Talloc0(owner_pubdata->pubkey_size);
		if(owner_pubdata->pubkey_data==NULL)
			return -ENOMEM;	
		Memcpy(owner_pubdata->pubkey_data,pubkey_XY,owner_pubdata->pubkey_size);	
		memdb_store(owner_pubdata,TYPE_PAIR(OWNER,PUBLIC_DATA),NULL);
	}
	else
	{
		owner_pubdata=db_record->record;
		if(owner_pubdata==NULL)
			return -EINVAL;
	}

	new_msg=message_create(TYPE_PAIR(OWNER,PUBLIC_DATA),recv_msg);
	if(new_msg==NULL)
		return -EINVAL;
	message_add_record(new_msg,owner_pubdata);
	ret=ex_module_sendmsg(sub_proc,new_msg);
	return ret;
}
